
//不写泛型了，直接让这个队列里面存储字符串
//基于数组 --环形队列（首尾相接）
class MyBlockingQueue{
    //此处这里的最大长度，也可以指定构造方法，由构造方法的参数来指定
    private String[] data=new String[1000];
    private volatile int head=0;//队列的起始位置
    private volatile int tail=0;//队列的结束位置的下一个位置
    private volatile int size=0;//队列有效元素的个数

    //private final Object locker=new Object();
    public void put(String elem) throws InterruptedException {
        synchronized (this){
            while(size== data.length){
                //队列满了--普通队列直接return即可
                //阻塞对列--满了继续插入元素就会阻塞
                    this.wait();
                //有另外一个线程调用take()释放元素则被唤醒
            }
            //队列未满，添加元素
            data[tail]=elem;
            tail++;
            if(tail==data.length){
                tail=0;
            }
            size++;
            this.notify();//这个notify用来唤醒take(0中的wait()
        }
    }
    public String take() throws InterruptedException {
        synchronized (this){
            while (size==0){
                //对于普通队列-直接return
                this.wait();
            }
            String ret=data[head];
            head++;
            if(head==data.length){
                head=0;
            }
            size--;
            this.notify();//此时说明释放了一个元素，notify()用来唤醒put()中的wait
            return ret;
        }
    }
}

public class demo {
    public static void main(String[] args) {
        MyBlockingQueue mbqueue = new MyBlockingQueue();

        //生产者生产慢，消费者消费快

        //消费者
        Thread t1 = new Thread(() -> {
            while (true){
                String result= null;
                try {
                    result = mbqueue.take();
                    System.out.println("消费元素："+result);
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });

        //生产者
        Thread t2 = new Thread(() -> {
            int num=1;
            while (true){
                try {
                    mbqueue.put(num+"");
                    System.out.println("生产者元素："+num);
                    num++;

                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }

            }
        });
        t1.start();
        t2.start();
    }
}
